package com.yuyou.fn.balance.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.balance.entity.TmsBalanceTransfer;
import com.yuyou.fn.balance.mapper.TmsBalanceTransferMapper;
import com.yuyou.fn.balance.service.ITmsBalanceTransferService;
import com.yuyou.fn.balance.vo.TmsBalanceTransferQueryVo;
import com.yuyou.fn.balance.vo.TmsStudentAccount;
import com.yuyou.fn.balance.vo.TmsTransferResult;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.Principals;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.Student;
import com.yuyou.fn.educational.service.IStudentService;
import com.yuyou.fn.settlement.entity.AccountRecharge;
import com.yuyou.fn.settlement.service.IAccountRechargeService;
import com.yuyou.fn.settlement.service.ISettlementService;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 *
 * TmsBalanceTransfer 表数据服务层接口实现类
 *
 */
@Service
public class TmsBalanceTransferServiceImpl extends SuperServiceImpl<TmsBalanceTransferMapper, TmsBalanceTransfer,Long> implements ITmsBalanceTransferService {

    @Resource
    private IStudentService studentService;

    @Resource
    private IAccountRechargeService accountRechargeService;

    @Resource
    private ISiteConfigService siteConfigService;


    @Resource
    private ISettlementService settlementService;

    @Value("${dev.env}")
    private boolean dev;

    @Override
    public Page<TmsBalanceTransfer> findCompleteTmsBalanceTransferPage(TmsBalanceTransferQueryVo tmsBalanceTransferQueryVo, int pageNo, int pageSize) {
        Example<TmsBalanceTransfer> example=TmsBalanceTransfer.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,tmsBalanceTransferQueryVo);
        criteria.andEqualTo("transferStatus",1);
        example.orderBy("createTime").desc();
        return findPageByExample(example,pageNo,pageSize);
    }

    @Override
    public TmsBalanceTransfer savePrepareTmsBalanceTransfer(Long studentId,BigDecimal amount) {
        Principals.Principal principal=Principals.get();
        if (principal==null){
            throw new BusException("查不到操作人");
        }

        Student student=studentService.findById(studentId);
        if (student==null){
            throw new BusException("查不到该学生");
        }
        TmsBalanceTransfer tmsBalanceTransfer=new TmsBalanceTransfer();
        tmsBalanceTransfer.setStudentId(student.getStudentId());
        tmsBalanceTransfer.setStudentName(student.getName());
        tmsBalanceTransfer.setStudentNo(student.getStudentNo());
        tmsBalanceTransfer.setOperatorId(principal.id);
        tmsBalanceTransfer.setOperatorName(principal.name);
        tmsBalanceTransfer.setCreateTime(TimeUtils.now());
        tmsBalanceTransfer.setUpdateTime(TimeUtils.now());
        tmsBalanceTransfer.setCheckStatus(0);
        tmsBalanceTransfer.setTransferStatus(0);
        tmsBalanceTransfer.setAmount(amount);
        tmsBalanceTransfer.setStudentPhoneNo(student.getPhoneNo());
        this.insert(tmsBalanceTransfer);
        return tmsBalanceTransfer;
    }

    @Override
    public SXSSFWorkbook exportCompleteTmsBalanceTransfer(TmsBalanceTransferQueryVo tmsBalanceTransferQueryVo) {
        Page<TmsBalanceTransfer> tmsBalanceTransferPage=this.findCompleteTmsBalanceTransferPage(tmsBalanceTransferQueryVo,1,20000);
        return tmsBalanceTransfer2Excel(tmsBalanceTransferPage.getRecords());
    }

    public static SXSSFWorkbook tmsBalanceTransfer2Excel(List<TmsBalanceTransfer> tmsBalanceTransferList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("学生余额迁移记录");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "学生姓名", "学号（誉优）","学号(TMS)", "手机号","转移余额", "操作人", "操作时间"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (tmsBalanceTransferList!=null){
            for (TmsBalanceTransfer tmsBalanceTransfer : tmsBalanceTransferList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(tmsBalanceTransfer.getStudentName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(tmsBalanceTransfer.getStudentNo()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(tmsBalanceTransfer.getStudentNo().replaceAll("zy","")));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(tmsBalanceTransfer.getStudentPhoneNo()));

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(tmsBalanceTransfer.getAmount()==null?0d:tmsBalanceTransfer.getAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(tmsBalanceTransfer.getOperatorName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(tmsBalanceTransfer.getCreateTime()==null?"": Utils.formatDate(tmsBalanceTransfer.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));


            }
        }
        return excel;
    }

    @Override
    public TmsStudentAccount queryTmsStudentBalance(Long studentId) {
        Student student=studentService.findById(studentId);
        if (!student.getStudentNo().contains("zy")){
            throw new BusException("TMS系统无“"+student.getName()+"”学员，无法完成转移！");
        }


        String url=dev?"http://demo.tms.zy.com/zytmsWS/api/queryStudentAccount?bizId=1":siteConfigService.findConfigValue("query_tms_student_balance");
        OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure(true).connectTimeout(30, TimeUnit.SECONDS ).readTimeout(10,TimeUnit.SECONDS).build();
        Map<String,String> params = new HashMap<>();
        String tmsSecretKey=siteConfigService.findConfigValue("tms_secret_key");
        String realStudentNo=student.getStudentNo().replaceAll("zy","");
        String secretKey= DigestUtils.md5Hex(realStudentNo+tmsSecretKey).toUpperCase();

        params.put("stuNumber" ,realStudentNo);
        params.put("studentPhone" ,student.getPhoneNo() );
        params.put("secretKey",secretKey);
        FormBody.Builder formBody = new FormBody.Builder();
        for(Map.Entry<String,String> entry : params.entrySet() ){
            formBody.add(entry.getKey(),entry.getValue());
        }
        try{
            Request request = new Request.Builder().url(url).post(formBody.build()).build() ;
            Response response = client.newCall(request).execute();
            if (response.code()!=200){
                throw new BusException("系统发生运行时错误");
            }else {
                String result=response.body().string();
                JSONObject jsonObject=JSONObject.parseObject(result);
                int code=jsonObject.getInteger("code");
                if (code!=1){
                    String message=jsonObject.getString("message");
                    throw new BusException(message);
                }else {
                    String data=jsonObject.getString("datas");
                    TmsStudentAccount tmsStudentAccount=JSONObject.parseObject(data,TmsStudentAccount.class);
                    return tmsStudentAccount;
                }
            }

        }catch (Exception e){
            throw new BusException(e.getMessage());
        }
    }

    @Override
    public TmsStudentAccount queryStudentDealBalance(Long studentId) {

        TmsStudentAccount tmsStudentAccount=this.queryTmsStudentBalance(studentId);
        TmsBalanceTransfer tmsBalanceTransfer=this.findUnComplete(studentId);
        if (tmsStudentAccount!=null && tmsBalanceTransfer!=null){
            tmsStudentAccount.setAvailableMoney(tmsBalanceTransfer.getAmount());
        }
        if (tmsStudentAccount!=null && (tmsStudentAccount.getAvailableMoney()==null || tmsStudentAccount.getAvailableMoney().doubleValue()==0d) ){
            throw new BusException("该学员在TMS的账户余额为零，无法完成转移！");
        }
        return tmsStudentAccount;
    }

    @Override
    public TmsTransferResult comfirmTransferTmsBalance(Long studentId,BigDecimal amount) {

        TmsTransferResult tmsTransferResult=this.transferTmsBalance(studentId,amount,false);
        if (tmsTransferResult==null){
            TmsStudentAccount  tmsStudentAccount=this.queryTmsStudentBalance(studentId);
            if (tmsStudentAccount==null || tmsStudentAccount.getAvailableMoney()==null){
                amount=BigDecimal.ZERO;
            }else {
                amount=tmsStudentAccount.getAvailableMoney();
            }
            tmsTransferResult=this.transferTmsBalance(studentId,amount,true);
        }
        return tmsTransferResult;

    }

    @Override
    public TmsTransferResult transferTmsBalance(Long studentId,BigDecimal amount,Boolean throwExecption) {
        TmsBalanceTransfer tmsBalanceTransfer=this.findOrCreatePrepareByStudentId(studentId,amount);
        if (amount==null || amount.doubleValue()==0d){
            throw new BusException("转移的金额不可为0或者剩余余额已为0");
        }
        Student student=studentService.findById(studentId);
        if (!student.getStudentNo().contains("zy")){
            throw new BusException("TMS系统无“"+student.getName()+"”学员，无法完成转移！");
        }

        TmsTransferResult tmsTransferResult=null;
        String url=dev?"http://demo.tms.zy.com/zytmsWS/api/transferStudentAccount?bizId=1":siteConfigService.findConfigValue("transfer_tms_student_balance");
        String tmsSecretKey=siteConfigService.findConfigValue("tms_secret_key");
        String realStudentNo=student.getStudentNo().replaceAll("zy","");

        OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure(true).connectTimeout(30, TimeUnit.SECONDS ).readTimeout(10,TimeUnit.SECONDS).build();
        String secretKey= DigestUtils.md5Hex(realStudentNo+tmsBalanceTransfer.getTmsBalanceTransferId()+tmsSecretKey).toUpperCase();
        Map<String,String> params = new HashMap<>();
        params.put("stuNumber" ,realStudentNo);
        params.put("secretKey",secretKey);
        params.put("transferMoney",tmsBalanceTransfer.getAmount().toString());
        params.put("serialNo",tmsBalanceTransfer.getTmsBalanceTransferId().toString());
        FormBody.Builder formBody = new FormBody.Builder();
        for(Map.Entry<String,String> entry : params.entrySet() ){
            formBody.add(entry.getKey(),entry.getValue());
        }
        try{
            Request request = new Request.Builder().url(url).post(formBody.build()).build() ;
            Response response = client.newCall(request).execute();
            if (response.code()!=200){
                if (throwExecption){
                    throw new BusException("系统发生运行时错误");
                }
            }else{
                String result=response.body().string();
                JSONObject jsonObject=JSONObject.parseObject(result);
                int code=jsonObject.getInteger("code");
                if (code!=1){
                    if (throwExecption){
                        String message=jsonObject.getString("message");
                        throw new BusException(message);
                    }
                }else {
                    String data=jsonObject.getString("datas");
                    tmsTransferResult=JSONObject.parseObject(data,TmsTransferResult.class);

                    this.completeTmsTransferBalance(tmsBalanceTransfer.getTmsBalanceTransferId(),tmsTransferResult.getTransferMoney());
                }
            }
        }catch (Exception e){
            if (throwExecption){
                throw new BusException(e.getMessage());
            }
        }
        return tmsTransferResult;
    }

    @Override
    public TmsBalanceTransfer findOrCreatePrepareByStudentId(Long studentId,BigDecimal amount) {
        Example<TmsBalanceTransfer> example=TmsBalanceTransfer.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("studentId",studentId);
        criteria.andEqualTo("transferStatus",0);
        TmsBalanceTransfer tmsBalanceTransfer=this.findOneByExample(example);
        if (tmsBalanceTransfer==null){
            tmsBalanceTransfer=this.savePrepareTmsBalanceTransfer(studentId,amount);
        }else {
            TmsBalanceTransfer update=new TmsBalanceTransfer();
            update.setAmount(amount);
            update.setTmsBalanceTransferId(tmsBalanceTransfer.getTmsBalanceTransferId());
            update.setUpdateTime(TimeUtils.now());
            this.updateSelectiveById(update);
        }
        return tmsBalanceTransfer;
    }

    @Override
    public TmsBalanceTransfer findUnComplete(Long studentId) {
        if (studentId==null){
            return null;
        }
        Example<TmsBalanceTransfer> example=TmsBalanceTransfer.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("studentId",studentId);
        criteria.andEqualTo("transferStatus",0);
        TmsBalanceTransfer tmsBalanceTransfer=this.findOneByExample(example);
        return tmsBalanceTransfer;
    }

    @Override
    @Transactional
    public void completeTmsTransferBalance(Long tmsBalanceTransferId,BigDecimal amount) {
        if (tmsBalanceTransferId==null){
            return;
        }
        TmsBalanceTransfer tmsBalanceTransfer=new TmsBalanceTransfer();
        tmsBalanceTransfer.setTmsBalanceTransferId(tmsBalanceTransferId);
        tmsBalanceTransfer.setTransferStatus(1);
        tmsBalanceTransfer.setUpdateTime(TimeUtils.now());
        tmsBalanceTransfer.setCompleteTime(TimeUtils.now());
        tmsBalanceTransfer.setAmount(amount);
        this.updateSelectiveById(tmsBalanceTransfer);
        TmsBalanceTransfer have=this.findById(tmsBalanceTransferId);
        /*tms默认广州区域*/
        AccountRecharge accountRecharge = accountRechargeService.prepareAccountRecharge(564701030634225664L,IdWorker.getId(),have.getStudentId(), null, null, have.getAmount(), "来自于tms", have.getOperatorId(), have.getOperatorName());
        accountRechargeService.finishAccountRecharge(accountRecharge.getAccountRechargeId(),6,null ,null , have.getAmount());
    }


}